package com.service.weChatWifiLogin.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.service.config.constant.ApiUrlConstants;
import com.service.config.utils.*;
import com.service.weChatWifiLogin.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.service.config.utils.DateUtil.*;

/**
 * @program: CloudCampusService
 * @description: 云管理Api封装
 * @author: rui
 * @create: 2021-03-31 14:26
 **/

@Component
@Slf4j
public class CloudCampusApi implements ApiUrlConstants {

    @Resource
    RestTemplate restTemplate;
    @Resource
    RedisUtil redisUtil;

    /**
     * 获取token
     *
     * @param username
     * @param password
     * @param requestHeaders
     * @return
     */
    public String getToken(String username, String password, HttpHeaders requestHeaders, String domain) {
        //获取token
        Map map = new HashMap();
        map.put("userName", username);
        map.put("password", password);
        try {
            HttpEntity<Map> requestEntity = new HttpEntity<Map>(map, requestHeaders);
            ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + CLOUD_CAMPUS_TOKEN_URL, HttpMethod.POST, requestEntity, JSONObject.class);
            return response.getBody().getJSONObject("data").getString("token_id");
        } catch (Exception e) {
            log.error("debug Token ==>" + e.getMessage());
            return null;
        }
    }


    /**
     * 获取站点site
     *
     * @param requestHeaders
     * @return
     */
    public List<SiteDto> getSites(HttpHeaders requestHeaders, String domain) {
        //获取站点
        boolean flag = true;
        int pageIndex = 1;
        List<SiteDto> siteDtos = new ArrayList<>();
        try {
            while (flag) {
                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + SITE_URL + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
                JSONArray data = response.getBody().getJSONArray("data");
                if (!data.isEmpty()) {
                    siteDtos.addAll(data.toJavaList(SiteDto.class));
                    pageIndex++;
                } else {
                    flag = false;
                }
            }
            return siteDtos;
        } catch (Exception e) {
            log.error("debug getSites ==>" + e.getMessage());
            return null;
        }
    }

    /**
     * 与云管理交互，增加ssid或更新
     * @param shopInfoDto
     * @param sites
     * @param token
     * @throws Exception
     */
    public void addSsId(ShopInfoDto shopInfoDto,List<SiteDto> sites,HttpHeaders token) throws Exception {
        SsidConfigDto ssidConfigDto = new SsidConfigDto();
        ssidConfigDto.setName(shopInfoDto.getSsidFlag()+"_"+shopInfoDto.getSsidName());
        AuthContentDto authContentDto = new AuthContentDto();
        authContentDto.setSecurityKey(shopInfoDto.getSsidPassword());
        ssidConfigDto.setSsidAuth(authContentDto);
        PolicyContentDto policyContentDto = new PolicyContentDto();
        if (shopInfoDto.getIsLimit()) { //0--false=不限流 1--true=限流
            //限速
            String upLimit = shopInfoDto.getUpLimit();
            if (StringUtils.isNotEmpty(upLimit) && !"0".equals(upLimit)) {
                RateLimitContentDto rateLimitContentDto = new RateLimitContentDto();
                rateLimitContentDto.setUpEnable(true);
                rateLimitContentDto.setDownEnable(true);
                BigDecimal kbBySeconds = new BigDecimal(upLimit).multiply(new BigDecimal(8));
                rateLimitContentDto.setUpLimit(kbBySeconds.toString()); // 上行限制
                rateLimitContentDto.setDownLimit(kbBySeconds.toString()); // 下限制
                policyContentDto.setSsidRateLimit(rateLimitContentDto);
            }else {
                // 默认
                RateLimitContentDto rateLimitContentDto = new RateLimitContentDto();
                rateLimitContentDto.setUpEnable(true);
                rateLimitContentDto.setDownEnable(true);
                BigDecimal kbBySeconds = new BigDecimal(1).multiply(new BigDecimal(8));
                rateLimitContentDto.setUpLimit(kbBySeconds.toString()); // 上行限制
                rateLimitContentDto.setDownLimit(kbBySeconds.toString()); // 下限制
                policyContentDto.setSsidRateLimit(rateLimitContentDto);
            }
        }
        ssidConfigDto.setSsidPolicy(policyContentDto);
        HttpEntity<SsidConfigDto> requestEntity = new HttpEntity<>(ssidConfigDto, token);
        //新增SSID信息
        if (!redisUtil.exist(shopInfoDto.getId())) {
            for (SiteDto siteId : sites) {
                //站点与SSID是一对多的关系
                //添加之后需要绑定站点与SSID的关系
                ResponseEntity<JSONObject> response = restTemplate.exchange(URL_FIRST+shopInfoDto.getDomain()+SS_ID_ADD_URL + siteId.getId() + "/apssid", HttpMethod.POST, requestEntity, JSONObject.class);
                JSONObject responseBody = response.getBody();
                if ("0".equals(responseBody.getString("errcode"))) {
                    SsidDto data = ModelMapperUtil.strictMap(responseBody.getJSONObject("data"), SsidDto.class);
                    data.setSiteId(siteId.getId());
                    redisUtil.leftPush(shopInfoDto.getId(), JsonXMLUtils.obj2json(data));
                }
            }
        }else { // 更新ssid
            List list = redisUtil.getList(shopInfoDto.getId());
            redisUtil.delete(shopInfoDto.getId());
            for (SiteDto siteId : sites) {
                //站点与SSID是一对多的关系
                //添加之后需要绑定站点与SSID的关系
                List<SsidDto> ssidDtoList = new ArrayList<>();
                for (Object o : list) {
                    ssidDtoList.add(JsonXMLUtils.json2obj(o.toString(),SsidDto.class));
                }
                List<SsidDto> collect = ssidDtoList.stream().filter(ssidDto -> ssidDto.getSiteId().equals(siteId.getId())).collect(Collectors.toList());
                if (collect.size()>0) {
                    ResponseEntity<JSONObject> response = restTemplate.exchange(URL_FIRST+shopInfoDto.getDomain()+ApiUrlConstants.SS_ID_UPDATE_URL + siteId.getId() + "/apssid/" + collect.get(0).getId(), HttpMethod.PUT, requestEntity, JSONObject.class);
                    JSONObject responseBody = response.getBody();
                    if ("0".equals(responseBody.getString("errcode"))) {
                        SsidDto data = ModelMapperUtil.strictMap(responseBody.getJSONObject("data"), SsidDto.class);
                        data.setSiteId(siteId.getId());
                        redisUtil.leftPush(shopInfoDto.getId(), JsonXMLUtils.obj2json(data));
                    }
                }
            }
        }
    }
    public void deleteSsId(String id, HttpHeaders requestHeaders,String domain) throws Exception {
        List<SsidDto> ssidDtoList = new ArrayList<>();
        if (redisUtil.exist(id)){
            List list = redisUtil.getList(id);
            for (Object o : list) {
                ssidDtoList.add(JsonXMLUtils.json2obj(o.toString(),SsidDto.class));
            }
            redisUtil.delete(id);
            ssidDtoList.stream().forEach(ssidDto -> {
                HashMap map = new HashMap();
                map.put("ids",Arrays.asList(ssidDto.getId()));
                HttpEntity<Map> requestEntity = new HttpEntity<>(map, requestHeaders);
                ResponseEntity<JSONObject> response = restTemplate.exchange(URL_FIRST+domain+ApiUrlConstants.SS_ID_DEL_URL + ssidDto.getSiteId() + "/apssid", HttpMethod.DELETE, requestEntity, JSONObject.class);
                JSONObject responseBody = response.getBody();
                if ("0".equals(responseBody.getString("errcode"))) {
                    log.info("success");
                }

            });
        }
    }
//    /**
//     * 获取设备列表信息
//     *
//     * @param sites
//     * @param requestHeaders
//     * @param
//     * @return
//     */
//    public List<DeviceDto> getDevices(List<SiteDto> sites, HttpHeaders requestHeaders, String domain) {
//        //查询设备(默认查询站点下所有设备)
//        List<DeviceDto> deviceDtos = new ArrayList<>();
//        try {
//            sites.forEach(site -> {
//                AtomicBoolean flag = new AtomicBoolean(true);
//                AtomicInteger pageIndex = new AtomicInteger(1);
//                String siteId = site.getId();
//                while (flag.get()) {
//                    HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                    ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + DEVICES_URL + "?pageSize=100&pageIndex=" + pageIndex + "&siteId=" + siteId, HttpMethod.GET, requestEntity, JSONObject.class);
//                    JSONArray data = response.getBody().getJSONArray("data");
//                    if (!data.isEmpty()) {
//                        deviceDtos.addAll(data.toJavaList(DeviceDto.class));
//                        pageIndex.getAndIncrement();
//                    } else {
//                        flag.set(false);
//                    }}
//            });
//            return deviceDtos;
//        } catch (Exception e) {
//            log.error("debug getDevices ==>" + e.getMessage());
//            return null;
//        }
//    }
//
//
//    /**
//     * 获取实时接入用户=====>未使用!!
//     *
//     * @param sites
//     * @param requestHeaders
//     * @return
//     */
//    public List<PortalUserDto> getProtalUsers(List<SiteDto> sites, HttpHeaders requestHeaders) {
//
//        //查询起始时间
//        Long endTimeLong = 1617243736090L;
//        Long beginTimeLong = 1617243016000L;
//
//        List<PortalUserDto> portalUserDtos = new ArrayList<>();
//        sites.forEach(site -> {
//            AtomicBoolean flag = new AtomicBoolean(true);
//            AtomicInteger pageIndex = new AtomicInteger(1);
//            while (flag.get()) {
//                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                ResponseEntity<JSONObject> response = restTemplate.exchange(PROTAL_ONLINE_USER + "?pageSize=100&pageIndex=" + pageIndex + "&beginTimeLong=" + beginTimeLong + "&endTimeLong=" + endTimeLong + "&siteId=" + site.getId(), HttpMethod.GET, requestEntity, JSONObject.class);
//                JSONArray data = response.getBody().getJSONArray("data");
//                if (!data.isEmpty()) {
//                    portalUserDtos.addAll(data.toJavaList(PortalUserDto.class));
//                    pageIndex.getAndIncrement();
//                } else {
//                    flag.set(false);
//                }
//            }
//        });
//        return portalUserDtos;
//    }
//
//
//    /**
//     * 获取查询终端TopN应用流量(维度：day  Top:5  APP)
//     *
//     * @param sites
//     * @param requestHeaders
//     */
//    public List<AppInfoDto> getAPPTrafficDetail(List<SiteDto> sites, HttpHeaders requestHeaders, String domain) {
//        try {
//            List<AppInfoDto> appInfoDtos = new ArrayList<>();
//            sites.forEach(site -> {
//                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + APP_TRAFFIC+site.getId(), HttpMethod.GET, requestEntity, JSONObject.class);
//                JSONArray data = response.getBody().getJSONArray("data");
//                if (!data.isEmpty()) {
//                    List<AppInfoDto> list = data.toJavaList(AppInfoDto.class);
//                    list.forEach(appInfoDto -> appInfoDto.setSiteId(site.getId()));
//                    appInfoDtos.addAll(list);
//                }
//            });
//            return appInfoDtos;
//        } catch (Exception e) {
//            log.error("debug getAPPTrafficDetail ==>" + e.getMessage());
//            return null;
//        }
//    }
//
//
//    /**
//     * 查询（0点，当前时间）区间的流量
//     *
//     * @param requestHeaders
//     * @param
//     * @param
//     */
//    public List<DeviceTrafficDto> getDeviceTrafficDetail(List<SiteDto> sites, HttpHeaders requestHeaders, String domain, String requestParm) {
//        try {
//            List<DeviceTrafficDto> list = new ArrayList<>();
//            sites.forEach(site -> {
//                String url = "https://" + domain + DEVICE_TRAFFIC + site.getId() + requestParm;
//                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                ResponseEntity<JSONObject> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JSONObject.class);
//                JSONArray data = response.getBody().getJSONArray("data");
//                if (!data.isEmpty()) {
//                    List<DeviceTrafficDto>  deviceStatisticInfoDtos= data.toJavaList(DeviceTrafficDto.class);
//                    deviceStatisticInfoDtos.forEach(deviceStatisticInfoDto -> deviceStatisticInfoDto.setSiteId(site.getId()));
//                    list.addAll(deviceStatisticInfoDtos);
//
//                }
//            });
//            return list;
//        } catch (Exception e) {
//            log.error("debug getDeviceTrafficDetail ==>" + e.getMessage());
//            return null;
//        }
//    }
//
//
//
//
//
//
//
//    /**
//     * 调用查询实时接入客户数量接口，每五分钟查询一次
//     *
//     * @param
//     * @param requestHeaders
//     * @return
//     */
//    public List<RealTimeDto> getDetailMinuDetil(List<SiteDto> sites, HttpHeaders requestHeaders, String domain) throws Exception {
//        try {
//            List<RealTimeDto> list = new ArrayList<>();
//            sites.forEach(site -> {
//                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + REAL_TIME_FLOW + site.getId(), HttpMethod.GET, requestEntity, JSONObject.class);
//                JSONArray data = response.getBody().getJSONArray("data");
//
//                RealTimeDto realTimeFlowDto = new RealTimeDto();
//                realTimeFlowDto.setSiteId(site.getId());
//                realTimeFlowDto.setName(site.getName());
//                realTimeFlowDto.setValue(0);
//
//                if (!data.isEmpty()) {
//                    for (int i = 0; i < data.size(); i++) {
//                        if ("REALTIME_HOUR_FLOW".equals(data.getJSONObject(i).getString("targetName"))) {
//                            Integer count = Integer.valueOf(data.getJSONObject(i).getJSONArray("counts").getJSONObject(0).getString("count"));
//                            realTimeFlowDto.setValue(count);
//                            break;
//                        }
//                    }
//                }
//                list.add(realTimeFlowDto);
//            });
//            return list;
//        } catch (Exception e) {
//            log.error("debug getDetailMinuDetil ==>" + e.getMessage());
//            return null;
//        }
//    }
//
//
//    /**
//     * 终端用户列表获取
//     *
//     *
//     * @param status  online---在线、offline---离线
//     * @param sites
//     * @param requestHeaders
//     * @return
//     */
//    public Map getTerminalUserList(String status, List<SiteDto> sites, HttpHeaders requestHeaders, String domain) {
//        DecimalFormat df = new DecimalFormat("#.00");
//        List<TerminalUserDto> list = new ArrayList<>();
//        Map map = new HashMap();
//        List<RealTimeDto> realTimeDtos = new ArrayList<>();
//        sites.forEach(site -> {
//            RealTimeDto realTimeDto = new RealTimeDto();
//            realTimeDto.setSiteId(site.getId());
//            realTimeDto.setName(site.getName());
//            AtomicBoolean flag = new AtomicBoolean(true);
//            AtomicInteger pageIndex = new AtomicInteger(1);
//            while (flag.get()) {
//                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
//                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + TERMINAL_USER_LIST + site.getId() + "?status="+status+"&pageSize=100&pageIndex=" + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
//                JSONArray data = response.getBody().getJSONArray("data");
//                realTimeDto.setValue(response.getBody().getInteger("total"));
//                if (!data.isEmpty()) {
//                    List<TerminalUserDto> list1 = data.toJavaList(TerminalUserDto.class);
//                    list1.forEach(terminalUserDto -> {
//                        terminalUserDto.setSiteId(site.getId());
//                        terminalUserDto.setSiteName(site.getName());
////                        Double traffic = bytesToMb(terminalUserDto.getCumulativeTraffic().doubleValue());
////                        Double d = Double.valueOf(String.format("%.2f", (bytesToMb(terminalUserDto.getCumulativeTraffic().doubleValue()))));
//                        terminalUserDto.setCumulativeTraffic(Double.valueOf(String.format("%.2f", (bytesToMb(terminalUserDto.getCumulativeTraffic().doubleValue())))));
//                    });
//                    list.addAll(list1);
//                    pageIndex.getAndIncrement();
//                    flag.set(false);
//                    realTimeDtos.add(realTimeDto);
//                } else {
//                    flag.set(false);
//                }
//            }
//        });
//        map.put("realTimeDtos",realTimeDtos);
//        map.put("TerminalUserDto",list);
//        return map;
//    }
//    /**
//     * byte(字节)根据长度转成kb(千字节)和mb(兆字节)     *     * @param bytes     * @return
//     */
//    public static Double bytesToMb(Double bytes) {
//        BigDecimal filesize = new BigDecimal(bytes);
//        BigDecimal megabyte = new BigDecimal(1024 * 1024);
//        float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP).floatValue();
//        return Double.valueOf(returnValue);
//    }
}
